vue+xterm.js实现webssh踩坑之旅 | 您所在的位置:网站首页 › Xterminal SSH › vue+xterm.js实现webssh踩坑之旅 |
最近在做的项目需要使用xterminal实现网页远程连接Linux终端,引了这个插件后发现问题很多,接下来一一记录问题所在。 一、如何在vue项目中使用xterm.js 安装xterm.js,博主使用的是3.x npm i xterm --save在项目中引用 新建组件Xterminal.vue import { Terminal } from "xterm"; import * as fit from "xterm/lib/addons/fit/fit"; import * as attach from "xterm/lib/addons/attach/attach"; import "xterm/dist/xterm.css"; Terminal.applyAddon(attach); Terminal.applyAddon(fit); export default { name: "xterminal", data() { return { term: null, terminalSocket: null, copy: '', loading: true, cols: 80, content: '' }; }, methods: { runRealTerminal(res) { this.content.operate = 'connect'; // 根据后端需求调节建立连接时发送的数据 this.terminalSocket.send( JSON.stringify(this.content) ); this.loading = false; console.log("webSocket is finished"); }, closeRealTerminal() { console.log("close"); } }, mounted() { let terminalContainer = document.getElementById("terminal"); this.term = new Terminal({ // 光标闪烁 cursorBlink: true }); this.term.open(terminalContainer, true); // open websocket this.terminalSocket = new WebSocket("ws://********"); // 填入服务器的websocket连接地址 this.terminalSocket.onopen = this.runRealTerminal; this.terminalSocket.onclose = this.closeRealTerminal; this.terminalSocket.onerror = this.errorRealTerminal; this.term.attach(this.terminalSocket); this.term._initialized = true; console.log("mounted is going on"); this.term.on("data", (data) => { console.log("data", data); this.terminalSocket.send( JSON.stringify({ operate: "command", command: data }) ); }); }, beforeDestroy() { this.terminalSocket.close(); this.term.destroy(); }, };以上代码是我对webssh的初步实现,当代码编译通过,在浏览器上展示时,博主发现终端窗口的大小并没有占满容器。 针对这些问题,最初想到的办法是过去container的宽高,在初始化terminal时对cols及rows参数进行设置,但是container的高度只在终端初始化后才会被撑开,因此获取到的高度为0。最终想到的办法是获取浏览器的innerWidth和innerHeight,计算终端容器的宽高。如上图所示,终端的高度为 window.innerHeight - 140,宽度为window.innerWidth - 230px(只是举个例子)。之后初始化时进行设置,代码如下: const width = window.innerWidth - 230; const height = window.innerHeight - 140; this.cols = parseInt(width/9, 10); // 经过计算one col大约等同于9px this.term = new Terminal({ // 光标闪烁 cursorBlink: true, cols: this.cols, rows: parseInt(height/17, 10), // one row = 17px });本以为到此开发结束,结果有一天心血来潮输入命令狂按a的时候,命令行过长不会换行而且把前面的内容覆盖了,淦!如下图所示。 之后确实实现了可换行的效果,但是问题又出现了,就是在浏览器缩放或放大的时候,终端内容消失了而且经常无法输入。这是因为没有使用fit()函数使其自适应。解决办法:在浏览器resize的时候调用fit函数。 在mounted钩子函数中加入:window.addEventListener('resize',this.windowChange); 在methods中定义: windowChange(){ const width = window.innerWidth - 230; const height = window.innerHeight - 140; this.cols = parseInt(width/9, 10); this.term.fit(); this.term.resize(this.cols, parseInt(height/17, 10)); this.term.scrollToBottom(); }同时需要向后端通过websocket发送最新的cols值。 至此,问题全部解决。end. |
CopyRight 2018-2019 实验室设备网 版权所有 |